一文搞懂 peerDependencies

您所在的位置:网站首页 Odyssey react2 一文搞懂 peerDependencies

一文搞懂 peerDependencies

2023-04-18 11:33| 来源: 网络整理| 查看: 265

背景

最近在做一个基于 Bulma 的 React 组件库,内部依赖了 React 库。

起初我自然而然的将其作为项目依赖直接添加进来:

yarn add react 复制代码

开发期间将项目通过 yarn link 的方式 link 到测试应用中,以便预览组件效果。

这时问题出现了:当组件库中有组件使用到 hook 的时候,就会报错,错误信息如下:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem. 复制代码

大概意思是说:hook 被非法调用了,Hooks 的调用位置不对,该错误有三种产生原因。

经过再三确认,错误的原因只可能是第三条:项目中依赖的 React 不唯一。

通过下面的鉴别方法,控制台返回 false,证明错误推断无误。

// Add this in node_modules/react-dom/index.js window.React1 = require('react'); // Add this in your component file require('react-dom'); window.React2 = require('react'); console.log(window.React1 === window.React2); 复制代码

正在我百思不得其解时,下面这句话点醒了我:

For example, maybe a library you’re using incorrectly specifies react as a dependency (rather than a peer dependency). Until that library is fixed, Yarn resolutions is one possible workaround.

自己的组件库中依赖了 react,按照说明,需要将其声明为 peerDependencies,这又是什么呢?

初始 peerDependencies

在 Node.js 的官网中有对 peerDependencies 的一个简要说明。

我们的组件库名称为 nass-design,在未使用 peerDependencies 之前,项目依赖组件库后的依赖树是这样子的:

App ├── [email protected] └─┬ [email protected] └── [email protected] 复制代码

此时,nass-design 有自己的 React 副本可以使用,并未使用外部的 React 依赖。

一般来说,这样是非常好的,每个人的代码之间都不会相互干扰,但是对于插件、组件库这样的应用场景来说就会存在问题,这也是上面的问题产生的根本原因。

可能你已经留意到在大多数插件中,都使用了 peerDependencies,例如 webpack 插件 html-webpack-plugin 中的依赖声明:

"peerDependencies": { "webpack": "^5.20.0" } 复制代码

它旨在与用户的项目共用一个 webpack 依赖。

将我们的组件库依赖的 react 改为 peerDependencies 后执行 npm update 重新安装依赖,此时项目的依赖树发生了变化:

App ├── [email protected] └── [email protected] 复制代码

可以看到 react 依赖就只被安装了一次,上面的问题就已经被解决了。

此时运行程序发现新的错误,react 依赖没有找到,这是因为 peerDependencies 中的依赖未被引入使用时不会默认安装。

external

为你使用的打包工具配置 external 选项,该选项表明需要被额外安装的依赖。

例如,在 esbuild 配置中:

esbuild.build({ entryPoints: 'entry', outfile: 'outfile', platform: 'browser', bundle: true, format: 'esm', minify: false, allowOverwrite: true, watch: true, target: 'es2020', external: [ // 需要额外安装的依赖 'react', 'react-dom', ], }); 复制代码

此时启动程序即可正常运行。

最后

最后贴出项目地址:github.com/nass-design…

该项目旨在打造一款适用于用户端(非后台管理系统)的 React UI 框架用于学习交流,后期会考虑作成完整生态,包括内置此 UI 风格的博客构建器。欢迎广大热爱技术的小伙伴与我共建!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3